<template>
	<view class="content">
		<view style="" class="topvg">
			<view style="width: 100%;display: flex;justify-content: space-between;padding: 50rpx;">
				<view style="display: flex;align-items: center;">
					<view @click="changecamera" class="btnitem" style="">
						<image src="/static/images/qqhsxt.png" style="width: 60rpx;" mode="widthFix"></image>
					</view>
					<view @click="showself = !showself" class="btnitem" style="margin-left: 20rpx;">
						<image src="/static/images/sshow.png" style="width: 60rpx;" mode="widthFix"></image>
					</view>
					<view v-if="!uservddata.audio" class="btnitem" style="margin-left: 20rpx;">
						<image src="/static/images/dfab.png" style="width: 60rpx;" mode="widthFix"></image>
					</view>
				</view>
				<view style="font-size: 28rpx;color: #bec7df;">

				</view>
				<view style="width: 60rpx;">

				</view>
			</view>
		</view>
		<view v-show="showself"
			style="width: 240rpx;height: 400rpx; position: fixed;right: 40rpx;top: 130rpx;z-index: 101;border-radius: 16rpx;">
			<bgyx-video-item :uid="$store.state.user.user.id" :name="$store.state.user.user.name" radius="16rpx"
				:id="`bgyx_video_1`" :src="myvddata.stream" status="play" :video="myvddata.video"
				:audio="myvddata.audio" :muted="true" />
		</view>
		<view style="width: 100%;display: flex;flex-wrap: wrap;flex: 1;overflow-y: hidden;">
			<bgyx-video-item :uid="id" :name="name" :id="`bgyx_video_0`" :src="uservddata.stream" status="play"
				:video="uservddata.video" :audio="uservddata.audio" />

		</view>

		<view style="" class="btmvg">
			<view style="display: flex;width: 100%;align-items: center;justify-content: center;margin-bottom: 60rpx;">
				<view @click="changeaudio(false)" v-if="myvddata.audio" class="btnitem" style="">
					<image src="/static/images/mmic.png" style="width: 60rpx;" mode="widthFix"></image>
				</view>
				<view @click="changeaudio(true)" v-if="!myvddata.audio" class="btnitem" style="background: #ff5e5e66;">
					<image src="/static/images/mmic.png" style="width: 60rpx;" mode="widthFix"></image>
				</view>

				<view @click="exit" class="btnitem"
					style="margin-left: 80rpx;background: #ff5e5e;width: 140rpx;height: 140rpx;">
					<image src="/static/images/hhdown.png" style="width: 70rpx;" mode="widthFix"></image>
				</view>

				<view @click="changevideo(false)" v-if="myvddata.video" class="btnitem" style="margin-left: 80rpx;">
					<image src="/static/images/ccamera.png" style="width: 60rpx;" mode="widthFix"></image>
				</view>
				<view @click="changevideo(true)" v-if="!myvddata.video" class="btnitem"
					style="margin-left: 80rpx;background: #ff5e5e66;">
					<image src="/static/images/ccamera.png" style="width: 60rpx;" mode="widthFix"></image>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import config from '../../config.js'
	import {
		mapState
	} from 'vuex';
	import {
		pub,
		sub,
		unsub
	} from '../../common/event';
	import moment from 'moment/moment';
	export default {
		data() {
			return {
				id: '',
				name: '',
				src: '',
				showself: true,
				myvddata: '',
				uservddata: '',
				audio: true,
				video: true
			}
		},
		components: {

		},
		computed: {
			...mapState({
				info: function(state) {
					return state.friend.list.find(e => e.fid == this.id)
				}
			})
		},
		onBackPress(options) {
			console.log(147, options)
			if (options.from && options.from == 'backbutton') {
				return true
			}
			return false
		},
		onUnload() {
			unsub(`socket_touser_videocallpubdone_${this.id}`, this.handlesingle)
			unsub(`socket_touser_videocall_changeaudio`, this.changeuseraudio)
			unsub(`socket_touser_videocall_changevideo`, this.changeuservideo)
			unsub(`socket_touser_videocall_exit`, this.closeall)
		},
		onLoad({
			id
		}) {
			sub(`socket_touser_videocallpubdone_${id}`, this.handlesingle)
			sub(`socket_touser_videocall_changeaudio`, this.changeuseraudio)
			sub(`socket_touser_videocall_changevideo`, this.changeuservideo)
			sub(`socket_touser_videocall_exit`, this.closeall)
			this.id = id
			this.name = this.info.name
			this.publishStream({
				video: true,
				audio: true,
				videoType: 'face'
			})

		},
		methods: {
			changecamera: async function() {
				let videoType = this.myvddata.videoType
				if(videoType == "face"){
					videoType = "environment"
				}else{
					videoType = "face"
				}
				try{
					await this.myvddata.unpublish()
					this.publishStream({
						videoType,
						video:this.myvddata.video,
						audio:this.myvddata.audio,
					})
				}catch(e){
					//TODO handle the exception
				}
			},
			changeuseraudio: function(e) {
				this.uservddata.audio = e.audio
			},
			changeuservideo: function(e) {
				this.uservddata.video = e.video
			},
			changeaudio: function(e) {
				this.myvddata.muteAudio(e)
				this.myvddata.audio = e
				this.$socket.send({
					type: "touser_videocall_changeaudio",
					data: {
						to: {
							id: this.id
						},
						audio: e
					}
				})
			},
			changevideo: function(e) {
				this.myvddata.muteVideo(e)
				this.myvddata.video = e
				this.$socket.send({
					type: "touser_videocall_changevideo",
					data: {
						to: {
							id: this.id
						},
						video: e
					}
				})
			},
			closeall: async function(e) {
				try {
					await this.myvddata.unpublish()
					await this.uservddata.close()
				} catch (e) {
					//TODO handle the exception
				}
				uni.navigateBack()
			},
			exit: async function(e) {
				try {
					await this.myvddata.unpublish()
					await this.uservddata.close()
				} catch (e) {
					//TODO handle the exception
				}
				this.$socket.send({
					type: "touser_videocall_exit",
					data: {
						to: {
							id: this.id
						},
					}
				})
				uni.navigateBack()
			},
			handlesingle: async function(e) {
				this.subStream()
			},
			subStream: async function() {
				const roomId = "videocall"
				const id = this.id
				const pc = new RTCPeerConnection(null);
				pc.addTransceiver('audio', {
					direction: 'recvonly'
				});
				pc.addTransceiver('video', {
					direction: 'recvonly'
				});
				let offer = await pc.createOffer();
				let stream = new MediaStream();
				pc.ontrack = function(event) {
					console.log(event);
					stream.addTrack(event.track);
				};
				await pc.setLocalDescription(offer);
				let session = await new Promise(function(resolve, reject) {
					let data = {
						api: `${config.srsUrl}/rtc/v1/play/`,
						tid: id,
						streamurl: `webrtc://${config.ip}/${roomId}/${id}`,
						clientip: null,
						sdp: offer.sdp,
					};
					console.log('Generated offer: ', data);

					const xhr = new XMLHttpRequest();
					xhr.onload = function() {
						if (xhr.readyState !== xhr.DONE) return;
						if (xhr.status !== 200) return reject(xhr);
						const data = JSON.parse(xhr.responseText);
						console.log('Got answer: ', data);
						return data.code ? reject(xhr) : resolve(data);
					};
					xhr.open('POST', `${config.srsUrl}/rtc/v1/play/`, true);
					xhr.setRequestHeader('Content-type', 'application/json');
					xhr.send(JSON.stringify(data));
				});
				await pc.setRemoteDescription(
					new RTCSessionDescription({
						type: 'answer',
						sdp: session.sdp
					}),
				);

				function close() {
					stream.getTracks().forEach(function(track) {
						track.stop();
						stream.removeTrack(track);
					});
					// stream.close()
					pc.close();
					document.getElementById("bgyx_video_1").srcObject = null
				}

				const vdata = {
					id,
					roomId,
					pc,
					stream,
					audio: true,
					video: true,
					close,
				};

				this.uservddata = vdata
			},
			publishStream: async function(options) {
				const id = this.$store.state.user.user.id
				const roomId = 'videocall'
				const pc = new RTCPeerConnection(null);
				pc.addTransceiver('audio', {
					direction: 'sendonly'
				});
				pc.addTransceiver('video', {
					direction: 'sendonly'
				});
				const stream = await this.getStreamLoc({
					audio: true,
					video: {
						facingMode: options.videoType ? options.videoType : "environment"
					},
				})
				this.cameraType = options.videoType ? options.videoType : "environment"
				console.log(stream);
				stream.getTracks().forEach(function(track) {
					pc.addTrack(track);
					if (track.kind === 'audio') {
						if (options.audio === false) {
							track.enabled = false;
						}
					}
					if (track.kind === 'video') {
						if (options.video === false) {
							track.enabled = false;
						}
					}
				});
				let offer = await pc.createOffer();
				await pc.setLocalDescription(offer);

				let session = await new Promise(function(resolve, reject) {
					let data = {
						api: `${config.srsUrl}/rtc/v1/publish/`,
						tid: id,
						streamurl: `webrtc://${config.ip}/${roomId}/${id}`,
						clientip: null,
						sdp: offer.sdp,
					};
					console.log('Generated offer: ', data);

					const xhr = new XMLHttpRequest();
					xhr.onload = function() {
						if (xhr.readyState !== xhr.DONE) return;
						if (xhr.status !== 200) return reject(xhr);
						const data = JSON.parse(xhr.responseText);
						console.log('Got answer: ', data);
						if (data.code === 400) {
							resolve(false);
						}
						return data.code ? reject(xhr) : resolve(data);
					};
					xhr.open('POST', `${config.srsUrl}/rtc/v1/publish/`, true);
					xhr.setRequestHeader('Content-type', 'application/json');
					xhr.send(JSON.stringify(data));
				});

				console.log(session);
				if (session === false) {
					return false;
				}
				await pc.setRemoteDescription(
					new RTCSessionDescription({
						type: 'answer',
						sdp: session.sdp
					}),
				);

				function muteAudio(type) {
					stream.getTracks().forEach(function(track) {
						if (track.kind === 'audio') {
							track.enabled = type ? type : false;
						}
					});
				}

				function muteVideo(type) {
					stream.getTracks().forEach(function(track) {
						if (track.kind === 'video') {
							track.enabled = type ? type : false;
						}
					});
				}
				const _this = this

				async function unpublish() {
					try {
						stream.getTracks().forEach(function(track) {
							track.stop();
							stream.removeTrack(track);
						});
						// stream.close()
						pc.close();
						_this.myvddata.stream = null
					} catch (e) {
						//TODO handle the exception
					}
				}

				const vdata = {
					id: id,
					roomId: roomId,
					pc,
					stream,
					audio: options.audio == false ? false : true,
					video: options.video == false ? false : true,
					videoType: options.videoType ? options.videoType : "environment",
					muteAudio,
					muteVideo,
					unpublish,
				};

				this.myvddata = vdata

				this.$socket.send({
					type: `touser_videocallpubdone_${id}`,
					data: {
						to: {
							id: this.id
						},
					}
				})
			},
			getStreamLoc: async function(constraints) {
				if (navigator.mediaDevices.getUserMedia) {
					console.log('最新的标准API', navigator.mediaDevices.getUserMedia);
					const rs = await navigator.mediaDevices.getUserMedia(constraints)
					return rs
				} else if (navigator.webkitGetUserMedia) {
					console.log('webkit核心浏览器');
					const rs = await navigator.webkitGetUserMedia(constraints)
					return rs
				} else if (navigator.mozGetUserMedia) {
					console.log('firfox浏览器');
					const rs = await navigator.mozGetUserMedia(constraints);
					return rs
				} else if (navigator.getUserMedia) {
					console.log('旧版API');
					const rs = await navigator.getUserMedia(constraints);
					return rs
				} else {
					const rs = await navigator.mediaDevices.getUserMedia(constraints)
					return rs
				}
			},
		}
	}
</script>


<style scoped>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		width: 100%;
		height: 100vh;
		justify-content: space-between;
		overflow-y: hidden;
	}

	.btmvg {
		width: 100%;
		display: flex;
		height: 40%;
		background: linear-gradient(to bottom, #33333300, #111111);
		position: fixed;
		left: 0rpx;
		bottom: 0rpx;
		color: white;
		align-items: flex-end;
	}

	.topvg {
		width: 100%;
		display: flex;
		height: 40%;
		background: linear-gradient(to bottom, #111111, #33333300);
		position: fixed;
		left: 0rpx;
		top: 0rpx;
		color: white;
		align-items: flex-start;
		z-index: 99;
	}

	.btnitem {
		width: 120rpx;
		height: 120rpx;
		display: flex;
		align-items: center;
		justify-content: center;
		border-radius: 160rpx;
		background: #cfcfcf55;
	}
</style>